<template><div><h2 id="请求" tabindex="-1"><a class="header-anchor" href="#请求"><span>请求</span></a></h2>
<p>一个应用的请求是用 <code v-pre>yii\web\Request</code> 对象来表示的，该对象提供了诸如请求参数（通常是 GET 或 POST ）、HTTP 头、cookies、CSRF等信息。一般情况下，你可以通过 <code v-pre>\Yii::$app-&gt;request</code> 来调用 <code v-pre>request</code> 应用组件，以此访问相应的请求对象。</p>
<h2 id="请求参数" tabindex="-1"><a class="header-anchor" href="#请求参数"><span>请求参数</span></a></h2>
<p>要获取请求参数，你可以调用 <code v-pre>request</code> 组件的 [[yii\web\Request::get()]] 和 [[yii\web\Request::post()]] 方法。他们分别返回 <code v-pre>$_GET</code> 和 <code v-pre>$_POST</code> 的值，例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$request</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$get</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token comment">// 等价于: $get = $_GET;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$id</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'id'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token comment">// 等价于: $id = isset($_GET['id']) ? $_GET['id'] : null;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$id</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'id'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token comment">// 等价于: $id = isset($_GET['id']) ? $_GET['id'] : 1;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$post</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token comment">// 等价于: $post = $_POST;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$name</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token comment">// 等价于: $name = isset($_POST['name']) ? $_POST['name'] : null;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$name</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">''</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token comment">// 等价于: $name = isset($_POST['name']) ? $_POST['name'] : '';</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Info: 建议您像上面那样通过 <code v-pre>request</code> 组件来获取请求参数，而不是直接访问 PHP 预定义变量 <code v-pre>$_GET</code> 和 <code v-pre>$_POST</code>。这会让您更容易编写测试用例，因为，你可以伪造数据来创建一个模拟请求组件。</p>
</blockquote>
<p>当您实现 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/rest-quick-start.md" target="_blank" rel="noopener noreferrer">RESTful 接口</a> 的时候，经常需要获取通过 PUT、PATCH、DELETE 或其他的 <a href="#ec4932">请求方法</a> 提交上来的参数，你可以通过调用 [[yii\web\Request::getBodyParam()]] 方法来获取这些参数，例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$request</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回所有参数</span></span>
<span class="line"><span class="token variable">$params</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">bodyParams</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回参数 "id"</span></span>
<span class="line"><span class="token variable">$param</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">getBodyParam</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'id'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Info: 不同于 <code v-pre>GET</code> 参数，<code v-pre>POST</code>，<code v-pre>PUT</code>，<code v-pre>PATCH</code> 等这些提交上来的参数是在请求体中被发送的。当你通过上面介绍的方法访问这些参数的时候，<code v-pre>request</code> 组件会解析这些参数。你可以通过在应用主体的组件配置 [[yii\web\Request::parsers]] 属性来自定义怎样解析这些参数，示例如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'components'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'request'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\web\Request'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'parsers'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'application/json'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\web\JsonParser'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'multipart/form-data'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\web\MultipartFormDataParser'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></blockquote>
<h2 id="请求方法" tabindex="-1"><a class="header-anchor" href="#请求方法"><span>请求方法</span></a></h2>
<p>你可以通过 <code v-pre>Yii::$app-&gt;request-&gt;method</code> 表达式来获取当前请求使用的 HTTP 方法。这里还提供了一整套布尔属性用于检测当前请求是某种类型。例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$request</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isAjax</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* 该请求是一个 AJAX 请求 */</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isPjax</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* 该请求是一个 PJAX 请求 */</span> <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isGet</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span> <span class="token comment">/* 请求方法是 GET */</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isPost</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* 请求方法是 POST */</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isPut</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span> <span class="token comment">/* 请求方法是 PUT */</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isDelete</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span> <span class="token comment">/* 请求方法是 DELETE */</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isPatch</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span> <span class="token comment">/* 请求方法是 PATCH */</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isHead</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span> <span class="token comment">/* 请求方法是 HEAD */</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isOptions</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span> <span class="token comment">/* 请求方法是 OPTIONS */</span> <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isFlash</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* 该请求是一个 Adobe Flash or Adobe Flex 请求 */</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">isSecureConnection</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* 该请求是一个 HTTPS 请求 */</span> <span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="请求-url-解析" tabindex="-1"><a class="header-anchor" href="#请求-url-解析"><span>请求 URL 解析</span></a></h2>
<p><code v-pre>request</code> 组件提供了许多方式来检测当前请求的 URL，并获取 URL 的各个部分，示例如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">//假设请求链接是 `http://example.com/admin/index.php/product?id=100`</span></span>
<span class="line"><span class="token variable">$request</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `http://example.com/admin/index.php/product?id=100`, 包含主机信息的整个URL</span></span>
<span class="line"><span class="token variable">$absoluteUrl</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">absoluteUrl</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `http://example.com`，只有主机信息</span></span>
<span class="line"><span class="token variable">$hostInfo</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">hostInfo</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `example.com`，只有主机的名称部分</span></span>
<span class="line"><span class="token variable">$hostName</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">hostName</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `/admin/index.php/product?id=100`, 不包括主机信息部分</span></span>
<span class="line"><span class="token variable">$url</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">url</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `/admin/index.php`，没有路径信息和查询字符串部分</span></span>
<span class="line"><span class="token variable">$scriptUrl</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">scriptUrl</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `/admin`，主机信息之后，入口脚本之前的部分</span></span>
<span class="line"><span class="token variable">$baseUrl</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">baseUrl</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `/product`，这个是入口脚本之后，? 之前（查询字符串）的部分</span></span>
<span class="line"><span class="token variable">$pathInfo</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">pathInfo</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `id=100`，? 之后的部分</span></span>
<span class="line"><span class="token variable">$queryString</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">queryString</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `example.com`，URL 中的主机名</span></span>
<span class="line"><span class="token variable">$serverName</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">serverName</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 80，这是 web 服务中使用的端口</span></span>
<span class="line"><span class="token variable">$serverPort</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">serverPort</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="http-头" tabindex="-1"><a class="header-anchor" href="#http-头"><span>HTTP 头</span></a></h2>
<p>您可以通过 [[yii\web\Request::headers]] 属性返回的 <code v-pre>yii\web\HeaderCollection</code> 获取 HTTP 头信息。例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// $headers 是一个 yii\web\HeaderCollection 对象</span></span>
<span class="line"><span class="token variable">$headers</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token property">headers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 Accept header 值</span></span>
<span class="line"><span class="token variable">$accept</span> <span class="token operator">=</span> <span class="token variable">$headers</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Accept'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$headers</span><span class="token operator">-></span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'User-Agent'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* 这是一个 User-Agent 头 */</span> <span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>request</code> 组件也提供了支持快速访问常用头的方法，例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$request</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `User-Agent` 头</span></span>
<span class="line"><span class="token variable">$userAgent</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">userAgent</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回 `Content-Type` 头的值，`Content-Type` 是请求体中 MIME 类型数据</span></span>
<span class="line"><span class="token variable">$contentType</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">contentType</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回用户可接受的内容 MIME 类型。返回的类型是按照他们的质量得分来排序的。得分最高的类型将被最先返回</span></span>
<span class="line"><span class="token variable">$acceptableContentTypes</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">acceptableContentTypes</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 返回用户可接受的语言。返回的语言是按照他们的偏好层次来排序的。第一个参数代表最优先的语言</span></span>
<span class="line"><span class="token variable">$acceptableLanguages</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">acceptableLanguages</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="首选语言" tabindex="-1"><a class="header-anchor" href="#首选语言"><span>首选语言</span></a></h2>
<p>假如，您的应用支持多语言，并且你想在终端用户最喜欢的语言中显示页面，那么你可以使用语言协商方法 [[yii\web\Request::getPreferredLanguage()]]。这个方法通过 [[yii\web\Request::acceptableLanguages]] 在你的应用中所支持的语言列表里进行比较筛选，返回最适合的语言，例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getPreferredLanguage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>Tip: 你也可以使用 <code v-pre>yii\filters\ContentNegotiator</code> 过滤器进行动态确定哪些内容类型和语言应该在响应中使用。这个过滤器实现了上面介绍的内容协商的属性和方法。</p>
</blockquote>
<h2 id="客户端信息" tabindex="-1"><a class="header-anchor" href="#客户端信息"><span>客户端信息</span></a></h2>
<p>你可以通过 <code v-pre>request</code> 组件获取发起请求的客户端机的主机名、IP 等信息， 例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$request</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 获取客户端主机名</span></span>
<span class="line"><span class="token variable">$userHost</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">userHost</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 获取客户端的 IP 地址</span></span>
<span class="line"><span class="token variable">$userIP</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">userIP</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="受信任的代理和报头" tabindex="-1"><a class="header-anchor" href="#受信任的代理和报头"><span>受信任的代理和报头</span></a></h2>
<p>在上一节中，您已经了解了如何获取主机和 IP 地址等用户信息。这将在正常设置中开箱即用，其中包括使用单个网络服务器为网站提供服务。然而，如果您的 Yii 应用程序在反向代理后面运行，则需要添加其他配置来检索此信息，因为直接客户端现在是代理，并且用户 IP 地址通过代理设置的报头传递给 Yii 应用程序。</p>
<p>除非您明确信任代理，否则不应盲目信任代理提供的报头。从 2.0.13 开始，Yii 支持通过 <code v-pre>request</code> 组件的 [[yii\web\Request::trustedHosts]] 、[[yii\web\Request::secureHeaders]] 、[[yii\web\Request::ipHeaders]] 和 [[yii\web\Request::secureProtocolHeaders]] 等属性配置可信代理。</p>
<p>以下是在反向代理数组后面运行的应用程序的请求配置，它们位于 <code v-pre>10.0.2.0/24</code> IP 网络中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'request'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'trustedHosts'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'10.0.2.0/24'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>默认情况下，IP 由代理在 <code v-pre>X-Forwarded-For</code> 头中发送，协议（“http”或“https”）在 <code v-pre>X-Forwarded-Proto</code> 中发送。</p>
<p>如果您的代理使用不同的报头，您可以使用请求配置来调整它们，例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'request'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'trustedHosts'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'10.0.2.0/24'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'X-ProxyUser-Ip'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'Front-End-Https'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'secureHeaders'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'X-Forwarded-For'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'X-Forwarded-Host'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'X-Forwarded-Proto'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'X-Proxy-User-Ip'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'Front-End-Https'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'ipHeaders'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'X-Proxy-User-Ip'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'secureProtocolHeaders'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'Front-End-Https'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'on'</span><span class="token punctuation">]</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>使用上面的配置，<code v-pre>secureHeaders</code> 中列出的所有报头都会从请求中过滤掉，除了 <code v-pre>X-ProxyUser-Ip</code> 和 <code v-pre>Front-End-Https</code> 报头，以防请求由代理发出。在这种情况下，前者用于检索 <code v-pre>ipHeaders</code> 中配置的用户IP，后者将用于确定 [[yii\web\Request::getIsSecureConnection()]] 的结果。</p>
<blockquote>
<p>💖喜欢本文档的，欢迎点赞、收藏、留言或转发，谢谢支持！<br>
作者邮箱：zhuzixian520@126.com，github地址：<a href="https://github.com/zhuzixian520" target="_blank" rel="noopener noreferrer">github.com/zhuzixian520</a></p>
</blockquote>
</div></template>


